package com.famid.flashcards;

import java.util.List;
import com.famid.flashcards.data.Card;
import com.famid.flashcards.data.CardStack;
import com.famid.flashcards.data.CardStackDAO;
import com.famid.flashcards.data.CardStackDAOImpl;
import com.famid.flashcards.data.CardsDAO;
import com.famid.flashcards.data.CardsDAOImpl;
import com.famid.flashcards.util.ShuffleCards;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Parcelable;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

public class CardsActivity extends Activity {
	
	private static final String TAG = CardsActivity.class.getSimpleName();
	private Context cxt;
	private CardsDAO cardsDao;
	private CardStackDAO stackDao;
	private long stackId;
	private List<Card> cards;
	private CardStack stack;
	private ViewPager vp;
	private PageOnPageChangeListener pageListener;
	private CardPagerAdapter adapter;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		cxt = this;
		pageListener = new PageOnPageChangeListener();
		adapter = new CardPagerAdapter();
		
		cardsDao = new CardsDAOImpl(cxt);
		cardsDao.open();
		
		stackDao = new CardStackDAOImpl(this);
		stackDao.open();
		
		vp = (ViewPager) findViewById(R.id.viewPager);
		vp.setAdapter(adapter);
		vp.setOnPageChangeListener(pageListener);
		
		Bundle bundle = this.getIntent().getExtras();
		stackId = bundle.getLong("stackId");
		
		cards = cardsDao.getAllCardsForStack(stackId);
		stack = stackDao.get(stackId);
	}
	
	@Override
	protected void onResume() {
		cardsDao.open();
		stackDao.open();
		cards = cardsDao.getAllCardsForStack(stackId);
		adapter.notifyDataSetChanged();
		Log.d(TAG, "Card activity resumed");
		super.onResume();
	}

	@Override
	protected void onPause() {
		cardsDao.close();
		stackDao.close();
		super.onPause();
	}
	
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		 switch (item.getItemId()) {
	        case R.id.flashcard_add:
	        	startAddActivity();
	            return true;
	        case R.id.flashcard_delete:
	        	deleteCard();
	        	return true;
	        case R.id.flashcard_edit:
	        	editCard();
	        	return true;
	        case R.id.flashcard_shuffle:
	        	shuffle();
	        	return true;
	        case R.id.flashcard_unshuffle:
	        	unshaffle();
	        	return true;
	        default:
	            return super.onOptionsItemSelected(item);
     }
	}
	
	private void unshaffle() {
		Log.d(TAG, "Unshuffle cards");
		cards = cardsDao.getAllCardsForStack(stackId);
		adapter.notifyDataSetChanged();
		Log.d(TAG, "Cards unshuffled successfully");
	}
	
	private void shuffle() {
		Log.d(TAG, "Shuffle cards");
		ShuffleCards.shuffle(cards);
		adapter.notifyDataSetChanged();
		Log.d(TAG, "Cards shuffled successfully");
	}
	
	private void deleteCard() {
		int currentPosition = pageListener.getCurrentPage();
		if(cards.size() > currentPosition) {
			Log.d(TAG, "Delete card: " + currentPosition);
			cardsDao.deleteCard(cards.get(currentPosition));
			cards.remove(currentPosition);
			adapter.notifyDataSetChanged();
			Toast.makeText(cxt, "Delete card: "+vp.isDrawingCacheEnabled(), Toast.LENGTH_SHORT).show();
		}
	}
	
	private void startAddActivity() {
		Intent mainIntent = new Intent(this, NewFlashCardActivity.class);
		Bundle bundle = new Bundle();
	    bundle.putLong("stackId", stackId);
	    mainIntent.putExtras(bundle);
		startActivity(mainIntent);
	}
	
	private void editCard() {
		Card card = cards.get(pageListener.getCurrentPage());
		Intent mainIntent = new Intent(this, NewFlashCardActivity.class);
		Bundle bundle = new Bundle();
	    bundle.putLong("stackId", stackId);
	    bundle.putBoolean("edit", true);
	    bundle.putString("Q", card.getQuestion());
	    bundle.putString("A", card.getAnswer());
	    bundle.putLong("cardId", card.getId());
	    mainIntent.putExtras(bundle);
		startActivity(mainIntent);
	}
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.flashcard_menu, menu);
        return true;
	}
	
	private class CardPagerAdapter extends PagerAdapter {

		@Override
		public int getCount() {
			return cards.size();
		}

		/**
		 * Create the page for the given position. The adapter is responsible
		 * for adding the view to the container given here, although it only
		 * must ensure this is done by the time it returns from
		 * {@link #finishUpdate()}.
		 * 
		 * @param container
		 *            The containing View in which the page will be shown.
		 * @param position
		 *            The page position to be instantiated.
		 * @return Returns an Object representing the new page. This does not
		 *         need to be a View, but can be some other container of the
		 *         page.
		 */
		@Override
		public Object instantiateItem(View collection, int position) {
			
			FlashCard fc = new FlashCard(cxt, cards.get(position), stack.getTitle());
			TextView tv = new TextView(cxt);
			Log.d(TAG, "instantiateItem "+position);
			tv.setText((position+1)+" of "+cards.size());
			tv.setTextColor(Color.parseColor("#adadad"));
			tv.setTextSize(10);
			tv.setGravity(Gravity.CENTER);
			
			RelativeLayout rl = new RelativeLayout(cxt);
			rl.addView(fc);
			
			RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.FILL_PARENT, RelativeLayout.LayoutParams.FILL_PARENT);
			params.addRule(RelativeLayout.CENTER_IN_PARENT);
			
			rl.setLayoutParams(params);
			fc.setLayoutParams(params);

			((ViewPager) collection).addView(rl, 0);
			return rl;
		}
		
		@Override
		public int getItemPosition(Object object) {
			return POSITION_NONE;
		}

		/**
		 * Remove a page for the given position. The adapter is responsible for
		 * removing the view from its container, although it only must ensure
		 * this is done by the time it returns from {@link #finishUpdate()}.
		 * 
		 * @param container - The containing View from which the page will be removed.
		 * @param position - The page position to be removed.
		 * @param object
		 *            The same object that was returned by
		 *            {@link #instantiateItem(View, int)}.
		 */
		@Override
		public void destroyItem(View collection, int position, Object view) {
			((ViewPager) collection).removeView((RelativeLayout) view);
		}

		@Override
		public boolean isViewFromObject(View view, Object object) {
			return view == ((RelativeLayout) object);
		}

		/**
		 * Called when the a change in the shown pages has been completed. At
		 * this point you must ensure that all of the pages have actually been
		 * added or removed from the container as appropriate.
		 * 
		 * @param container
		 *            The containing View which is displaying this adapter's
		 *            page views.
		 */
		@Override
		public void finishUpdate(View arg0) {
		}

		@Override
		public void restoreState(Parcelable arg0, ClassLoader arg1) {
		}

		@Override
		public Parcelable saveState() {
			return null;
		}

		@Override
		public void startUpdate(View arg0) {
		}
	}
	
	/**
     * Get the current view position from the ViewPager.
     */
    public class PageOnPageChangeListener extends ViewPager.SimpleOnPageChangeListener {

        private int currentPage;

        @Override
        public void onPageSelected(int position) {
            currentPage = position;
        }

        public int getCurrentPage() {
            return currentPage;
        }
    }
}